/**
 * Independent time operation tool to facilitate subsequent switch to dayjs
 */
import dayjs from 'dayjs';

import { useI18n } from '@/hooks/web/useI18n';
import { isNumber, isObject, isString } from '@/utils/is';

/** 一秒钟 */
export const ONE_SECONDS = 1000;
/** 一分钟 */
export const ONE_MINUTES = ONE_SECONDS * 60;
/** 一小时 */
export const ONE_HOUR = ONE_MINUTES * 60;
/** 一天 */
export const ONE_DAY = ONE_HOUR * 24;

/** 默认日期时间格式 */
export const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss';
/** 默认日期格式 */
export const DATE_FORMAT = 'YYYY-MM-DD';

/** 日期时间工具 */
export const dateUtil = dayjs;

/** 格式化日期时间
 * @param date 日期时间
 * @param [format] 格式类型 默认 'YYYY-MM-DD HH:mm:ss'
 */
export function formatToDateTime(date?: dayjs.ConfigType, format = DATE_TIME_FORMAT): string {
  if (date === '' || date === null || date === undefined) {
    return '';
  }
  return dayjs(date).format(format);
}

/** 格式化日期时间
 * @param date 日期时间
 * @param [format] 格式类型 默认 'YYYY-MM-DD'
 */
export function formatToDate(date?: dayjs.ConfigType, format = DATE_FORMAT): string {
  if (date === '' || date === null || date === undefined) {
    return '';
  }
  return dayjs(date).format(format);
}

/** 获取日期对应的星期
 * @param date 日期时间
 */
export function getDayOfWeek(date?: dayjs.ConfigType): string {
  return dayjs(date).format('dddd'); // 返回星期几的全称
}

/** 计算两个日期时间之间的差异
 * @param start 开始时间
 * @param end 结束时间
 * @param unit 差异单位
 * ```
Unit		Shorthand	Description
day		d		Day
week		w		Week of Year
quarter		Q		Quarter
month		M		Month (January as 0, December as 11)
year		y		Year
hour		h		Hour
minute		m		Minute
second		s		Second
millisecond	ms		Millisecond
 * ```
 * @param float 默认情况下，dayjs#diff会将结果截断到小数点后零位，返回一个整数。如果你想要一个浮点数，请将true作为第三个参数传递。
 * Docs: https://day.js.org/docs/en/display/difference
 */
export function diffBetween(
  start?: dayjs.ConfigType,
  end?: dayjs.ConfigType,
  unit?: dayjs.OpUnitType | dayjs.QUnitType,
  float?: boolean,
) {
  return dayjs(start).diff(dayjs(end), unit, float);
}
/** 计算两个日期时间之间的差异(天)
 * @param start 开始时间
 * @param end 结束时间
 */
export function daysBetween(start?: dayjs.ConfigType, end?: dayjs.ConfigType) {
  return diffBetween(start, end, 'day'); // 以天为单位计算差异
}

/** 获取时间戳
 * @param value 时间值
 */
export function getTimeStamp(value?: Date | number | string) {
  value = value || Date.now();
  let time = 0;
  if (isNumber(value)) {
    const timestamp = value.toString().length > 10 ? value : value * 1000;
    time = new Date(timestamp).getTime();
  } else if (isString(value)) {
    time = new Date(value).getTime();
  } else if (isObject(value)) {
    time = value.getTime();
  }
  return time;
}
/** 获取相对时间
 * @param timeStamp 时间戳
 */
export function getRelativeTime(timeStamp: number) {
  const { t: $t } = useI18n();

  const currentTime = Date.now();

  // Determine whether the incoming timestamp is earlier than the current timestamp
  const isBefore = dateUtil(timeStamp).isBefore(currentTime);

  let diff = currentTime - timeStamp;
  if (!isBefore) {
    diff = -diff;
  }

  let resStr = '';
  const dirStr = isBefore ? $t('component.time.before') : $t('component.time.after');

  if (diff < ONE_SECONDS) {
    resStr = $t('component.time.just');
    // Less than or equal to 59 seconds
  } else if (diff < ONE_MINUTES) {
    resStr = Number.parseInt(`${diff / ONE_SECONDS}`) + $t('component.time.seconds') + dirStr;
    // More than 59 seconds, less than or equal to 59 minutes and 59 seconds
  } else if (diff >= ONE_MINUTES && diff < ONE_HOUR) {
    resStr = Math.floor(diff / ONE_MINUTES) + $t('component.time.minutes') + dirStr;
    // More than 59 minutes and 59 seconds, less than or equal to 23 hours, 59 minutes and 59 seconds
  } else if (diff >= ONE_HOUR && diff < ONE_DAY) {
    resStr = Math.floor(diff / ONE_HOUR) + $t('component.time.hours') + dirStr;
    // More than 23 hours, 59 minutes and 59 seconds, less than or equal to 29 days, 59 minutes and 59 seconds
  } else if (diff >= ONE_DAY && diff < 2_623_860_000) {
    resStr = Math.floor(diff / ONE_DAY) + $t('component.time.days') + dirStr;
    // More than 29 days, 59 minutes, 59 seconds, less than 364 days, 23 hours, 59 minutes, 59 seconds, and the incoming timestamp is earlier than the current
  } else if (diff >= 2_623_860_000 && diff <= 31_567_860_000 && isBefore) {
    resStr = dateUtil(timeStamp).format('MM-DD-HH-mm');
  } else {
    resStr = dateUtil(timeStamp).format('YYYY');
  }
  return resStr;
}
